/* 
一.对象混入
可以使用es6的Object.assign 合并多个对象
此时 people 会被推断成一个交差类型 Name & Age & sex;

合并 A对象 B对象 合并到一起
*/

interface AMixins {
  age: number
}

interface BMixins {
  name: string
}

let aObj:AMixins = { age: 18 }
let bObj:BMixins = { name: "老李"}

// 1.扩展运算符 浅拷贝 返回新的类型
let cObj1 = {...aObj, ...bObj}
// 2.Object.assign 浅拷贝 返回交叉类型
let cObj2 = Object.assign(aObj, bObj)

// console.log(cObj1)
// console.log(cObj2)
// console.log(structuredClone(aObj)) // node18以上才支持 谷歌浏览器也需要较高版本

/* 
二.类的混入
首先声明两个mixins类 （严格模式要关闭不然编译不过）

A类 B类 合并到一起
*/

// 插件混入
class Logger {
  log(msg: string) {
    console.log(msg)
  }
}

class Html {
  render() {
    console.log("render")
  }
}

class App {
  run() {
    console.log("run")
  }
}

type Custructor<T> = new (...args: any[]) => T

function pluginMixins<T extends Custructor<App>>(Base: T) {
  return class extends Base {
    private Logger = new Logger()
    private Html = new Html()

    constructor(...args: any[]) {
      super(...args)

      this.Logger = new Logger()
      this.Html = new Html()
    }

    run() {
      this.Logger.log("run")  // 调用私有方法
    }

    render() {
      this.Logger.log("render") // 调用私有方法
      this.Html.render() // 调用私有方法
    }
  }
}

const mixins = pluginMixins(App)
const app = new mixins()
app.run()
